package com.jimo.app;

import static android.os.Process.myPid;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Toast;

import androidx.activity.EdgeToEdge;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

import com.bytecat.algui.ICommandService;
import com.jimo.api.ApiConstant;
import com.jimo.api.MemType;
import com.jimo.app.adp.MemTypeAdapter;
import com.jimo.app.adp.MemTypeAreaAdapter;
import com.jimo.app.bean.MemTypeBean;
import com.jimo.app.databinding.ActivityConnectBinding;
import com.jimo.app.util.Util;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;


public class ConnectActivity extends AppCompatActivity {

    private ICommandService service;
    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder binder) {
            service = ICommandService.Stub.asInterface(binder);
            refreshStatus();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            service = null;
            Toast.makeText(ConnectActivity.this, "服务已断开", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onBindingDied(ComponentName name) {
            ServiceConnection.super.onBindingDied(name);
        }

        @Override
        public void onNullBinding(ComponentName name) {
            ServiceConnection.super.onNullBinding(name);
        }
    };
    private MemTypeAreaAdapter memAreaAdapter;
    private MemTypeAdapter memTypeAdapter;
    private MemTypeBean typeBean;

    private void refreshStatus() {
        new Handler(Looper.getMainLooper()).postDelayed(() -> {
            if(service==null){
                bind.connectStatus1.setText("连接失败");
                bind.connectStatus1.setTextColor(getColor(R.color.red));
                bind.statusImg1.setBackground(getDrawable(R.drawable.status_not_connect));
                return;
            }

            bind.connectStatus1.setText("连接成功");
            bind.connectStatus1.setTextColor(getColor(R.color.black));
            bind.statusImg1.setBackground(getDrawable(R.drawable.status_connect));
            try {
                bind.tvAidlPid.setText("PID:"+service.getAidlPid());
            } catch (RemoteException e) {
                bind.tvAidlPid.setText("PID:获取失败");
            }

            try {
                if (service.isAidlConnectApp()) {
                    int mainProcessPid = service.getPid();
                    bind.tvMainProcessPid.setText("PID:"+mainProcessPid);
                    bind.connectStatus2.setText("连接成功");
                    bind.connectStatus2.setTextColor(getColor(R.color.black));
                    bind.statusImg2.setBackground(getDrawable(R.drawable.status_connect));
                } else {
                    bind.connectStatus2.setText("连接失败");
                    bind.connectStatus2.setTextColor(getColor(R.color.red));
                    bind.statusImg2.setBackground(getDrawable(R.drawable.status_not_connect));
                    bind.tvMainProcessPid.setText("PID:获取失败");
                }
            } catch (Exception e) {
                bind.connectStatus2.setText("连接失败");
                bind.connectStatus2.setTextColor(getColor(R.color.red));
                bind.statusImg2.setBackground(getDrawable(R.drawable.status_not_connect));
                bind.tvMainProcessPid.setText("PID:获取失败");
            }
        }, 1000);
    }


    private @NonNull ActivityConnectBinding bind;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        bind=ActivityConnectBinding.inflate(getLayoutInflater());
        setContentView(bind.getRoot());
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });
        bind.tvPidself.setText("PID:"+myPid());
        ActivityResultLauncher<Intent> launcher =
                registerForActivityResult(
                        new ActivityResultContracts.StartActivityForResult(),
                        result -> {
                            if (result.getResultCode() == RESULT_OK) {
                                Intent data = result.getData();
                                if (data != null) {
                                    String apkPath = data.getStringExtra("sourceDir");
                                    String packetName = data.getStringExtra("packageName");
                                    bind.packetName.setText("已选择"+packetName);
                                    Intent intent = new Intent(ApiConstant.CommandServiceName);
                                    intent.setPackage(packetName);
                                    try {unbindService(connection);}catch (Exception ignore){}
                                    bindService(intent, connection, Context.BIND_AUTO_CREATE);
                                    refreshStatus();
                                }
                            }
                        });
        bind.connectAidl.setOnClickListener(v -> {
            Intent intent = new Intent(ConnectActivity.this, AppListActivity.class);
            intent.putExtra("selectInjected",true);
            launcher.launch(intent);
        });
        bind.reconnect.setOnClickListener(v -> {
            if(service!=null){
                try {
                    service.bindAidlToApp();
                } catch (RemoteException e) {
                    throw new RuntimeException(e);
                }
            }else{
                Toast.makeText(this, "请先连接AIDL进程", Toast.LENGTH_SHORT).show();
            }
            refreshStatus();
        });
        bind.killSelf.setOnClickListener(v -> {
            if(service!=null){
                try {
                    service.killSelf(true);
                } catch (RemoteException e) {
                    throw new RuntimeException(e);
                }
            }else{
                Toast.makeText(this, "请先连接", Toast.LENGTH_SHORT).show();
            }
            refreshStatus();
        });
        bind.getCurrentMemType.setOnClickListener(v -> {
            if(service!=null){
                try {
                    Toast.makeText(this, "当前内存区域:"+service.getMemoryAreaName(), Toast.LENGTH_SHORT).show();
                } catch (RemoteException e) {
                    throw new RuntimeException(e);
                }
            }else{
                Toast.makeText(this, "请先连接", Toast.LENGTH_SHORT).show();
            }
        });

        bind.memAreaSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                if(service!=null){
                    try {
                        MemTypeBean bean = memAreaAdapter.getItem(position);
                        service.setMemoryArea(bean.value);
                        Toast.makeText(ConnectActivity.this, "已设置"+bean.name, Toast.LENGTH_SHORT).show();
                    } catch (RemoteException e) {
                        throw new RuntimeException(e);
                    }
                }else{
                    Toast.makeText(ConnectActivity.this, "请先连接", Toast.LENGTH_SHORT).show();
                }
            }
            @Override
            public void onNothingSelected(AdapterView<?> parent) {}
        });
        ArrayList<MemTypeBean>areaTypes= new ArrayList<>();
        areaTypes.add(new MemTypeBean("全部内存",MemType.RANGE_ALL));
        areaTypes.add(new MemTypeBean("A匿名内存",MemType.RANGE_ANONYMOUS));
        areaTypes.add(new MemTypeBean("AS安卓共享内存",MemType.RANGE_ASHMEM));
        areaTypes.add(new MemTypeBean("错误的内存区域",MemType.RANGE_B_BAD));
        areaTypes.add(new MemTypeBean("C++ 未初始化的内容(CB内存)",MemType.RANGE_C_BSS));
        areaTypes.add(new MemTypeBean("C++ 分配的内存(CA内存)",MemType.RANGE_C_ALLOC));
        areaTypes.add(new MemTypeBean("C++ 的数据段(CD内存)",MemType.RANGE_C_DATA));
        areaTypes.add(new MemTypeBean("C++ 堆内存(CH内存)",MemType.RANGE_C_HEAP));
        areaTypes.add(new MemTypeBean("应用程序代码区域",MemType.RANGE_CODE_APP));
        areaTypes.add(new MemTypeBean("系统代码区域",MemType.RANGE_CODE_SYSTEM));
        areaTypes.add(new MemTypeBean("Java 虚拟机内存",MemType.RANGE_JAVA));
        areaTypes.add(new MemTypeBean("Java 虚拟机堆内存",MemType.RANGE_JAVA_HEAP));
        areaTypes.add(new MemTypeBean("栈内存区域(s内存)",MemType.RANGE_STACK));
        areaTypes.add(new MemTypeBean("视频内存区域(v内存)",MemType.RANGE_VIDEO));
        areaTypes.add(new MemTypeBean("其他内存区域(o内存)",MemType.RANGE_OTHER));
        memAreaAdapter = new MemTypeAreaAdapter(this,areaTypes);
        bind.memAreaSpinner.setAdapter(memAreaAdapter);


        ArrayList<MemTypeBean>types= new ArrayList<>();
        types.add(new MemTypeBean("BYTE",MemType.TYPE_BYTE));
        types.add(new MemTypeBean("DOUBLE",MemType.TYPE_DOUBLE));
        types.add(new MemTypeBean("DWORD",MemType.TYPE_DWORD));
        types.add(new MemTypeBean("FLOAT",MemType.TYPE_FLOAT));
        types.add(new MemTypeBean("QWORD",MemType.TYPE_QWORD));
        types.add(new MemTypeBean("WORD",MemType.TYPE_WORD));
        memTypeAdapter = new MemTypeAdapter(this,types);
        bind.memTypeSpinner.setAdapter(memTypeAdapter);
        bind.memTypeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                 typeBean = memTypeAdapter.getItem(position);
            }
            @Override
            public void onNothingSelected(AdapterView<?> parent) {}
        });
        bind.search.setOnClickListener(v -> {
            if(service!=null){
                if(typeBean==null){
                    Toast.makeText(ConnectActivity.this,"请先选择搜索的类型",Toast.LENGTH_SHORT).show();
                    return;
                }
                try {
                    service.clearResultList();
                    long[] res = service.MemorySearch(bind.searchText.getText().toString(), typeBean.value);
                    Toast.makeText(ConnectActivity.this, Arrays.toString(res),Toast.LENGTH_SHORT).show();
                } catch (RemoteException e) {
                    throw new RuntimeException(e);
                }
            }else{
                Toast.makeText(this, "请先连接", Toast.LENGTH_SHORT).show();
            }
        });
        bind.test.setOnClickListener(v -> {
            if(service!=null){
                try {
                    Toast.makeText(ConnectActivity.this, service.getResultCount()+service.test(),Toast.LENGTH_SHORT).show();
                } catch (RemoteException e) {
                    throw new RuntimeException(e);
                }
            }else{
                Toast.makeText(this, "请先连接", Toast.LENGTH_SHORT).show();
            }
        });
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        try {
            unbindService(connection);
        } catch (Exception ignored) {}
    }

}